#include "vxeffects.h"


VxEffects * VxEffects::_instance = 0;

VxEffects::VxEffects()
{
}


class _HideSoft : public QObject
{
	Q_OBJECT
	Q_PROPERTY(int _opacity READ _getOpacity WRITE _setOpacity)

public:

	_HideSoft(QWidget * widget, int duration, bool destroy) :
			_widget(widget), _destroy(destroy),_opacity(0), _first(true)
	{
		_widgetPx = new QPixmap(_widget->size());
		_widgetPx->fill(Qt::transparent);


		_widget->render(_widgetPx, QPoint(0,0), QRegion(0,0, _widget->width(), _widget->height(), QRegion::Rectangle),
					QWidget::DrawChildren);


		QPropertyAnimation * animation = new QPropertyAnimation(this, "_opacity");
		animation->setDuration(duration);
		animation->setStartValue(255);
		animation->setEndValue(0);
		animation->start(QAbstractAnimation::DeleteWhenStopped);

		connect(animation, SIGNAL(finished()), this, SLOT(_hideFinished()));

		_widget->installEventFilter(this);


	}

protected:

	bool eventFilter(QObject * obj, QEvent * event)
	{
		if (event->type() != QEvent::Paint){
			return false;
		}

		if (_first){
			_first = false;
			foreach(QObject* obj, _widget->children()){
				QWidget * wg = static_cast<QWidget *>(obj);
				if (!wg->isVisible()){
					continue;
				}
				wg->hide();
				_hidden.append(wg);
			}
		}

		QPixmap pixmap(_widgetPx->size());
		pixmap.fill(Qt::transparent);

		QPainter p;
		p.begin(&pixmap);

		p.drawPixmap(0,0, *_widgetPx);

		p.setCompositionMode(QPainter::CompositionMode_DestinationIn);
		p.fillRect(pixmap.rect(), QColor(0, 0, 0, _opacity));
		p.end();

		QPainter painter(_widget);

		painter.drawPixmap(0, 0, pixmap);
		return true;
	}


private:
	QWidget * _widget;
	QPixmap * _widgetPx;
	bool _destroy;
	QVector<QWidget *> _hidden;

	int _opacity;
	bool _first;

	int _getOpacity()
	{
		return _opacity;
	};

	void _setOpacity(int opacity)
	{
		_opacity = opacity;
		_widget->repaint();;
	};



private slots:

	void _hideFinished()
	{
		_widget->removeEventFilter(this);
		_widget->hide();

		foreach(QWidget * wg, _hidden){
			wg->show();
		}

		delete _widgetPx;

		if (_destroy){
			delete _widget;
		}

		delete this;
	}
};


void VxEffects::hide(QWidget * widget, EffectType type, int duration, bool destroy)
{
	switch(type){
	case HideSoft:{
			_HideSoft * hide = new _HideSoft(widget, duration, destroy);
			Q_UNUSED(hide);
		}
	default:;
	}
}




#include "vxeffects.moc"
